using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.BO;
using Habanero.Faces.Base;
using Habanero.Faces.Win;

namespace FireStarterModeller.UI
{
    /// <summary>
    /// This is a control represeinting the wizard step for selecting <see cref="DMProperty"/>s of a <see cref="DMClass"/>
    /// </summary>
    public class SelectPropertiesWizardStep : WizardStepWin
    {
        private DMClass _selectedClass;
        private IBOComboBoxSelector _classSelectorControl;

        public IMultiSelector<string> PropertiesSelectorControl { get; private set; }

        private DMSolution _solution;
        private readonly ILabel _label;

        public SelectPropertiesWizardStep()
        {
            IControlFactory factory = GlobalUIRegistry.ControlFactory;
            
            ClassSelectorControl = factory.CreateComboBoxSelector();
            ClassSelectorControl.BusinessObjectCollection = null;
            ClassSelectorControl.AutoSelectFirstItem = false;
            PropertiesSelectorControl = factory.CreateMultiSelector<string>();
            IPanel panel = factory.CreatePanel();

            _label = factory.CreateLabel();
            ((LabelWin) _label).BorderStyle = BorderStyle.Fixed3D;
            _label.Font = new Font(_label.Font.FontFamily, _label.Font.Size + 1, FontStyle.Bold); ;
            BorderLayoutManager panelLayoutManager = factory.CreateBorderLayoutManager(panel);
            panelLayoutManager.AddControl(ClassSelectorControl, BorderLayoutManager.Position.North);
            panelLayoutManager.AddControl(PropertiesSelectorControl, BorderLayoutManager.Position.Centre);

            this.MaximumSize = new Size(600, 450);
            this.MinimumSize = new Size(600, 450);
            
            BorderLayoutManager layoutManager = factory.CreateBorderLayoutManager(this);
            layoutManager.AddControl(Label, BorderLayoutManager.Position.North);
            layoutManager.AddControl(panel, BorderLayoutManager.Position.Centre);

            ClassSelectorControl.BusinessObjectSelected += delegate(object sender, BOEventArgs e)
            {
                this.SelectedClass = (DMClass) e.BusinessObject;
            };
        }

        /// <summary>
        /// Initialises the step. Run when the step is reached.
        /// </summary>
        public override void InitialiseStep()
        {
        }

        /// <summary>
        /// Verifies whether this step can be passed.
        /// </summary>
        /// <param name="message">Error message should moving on be disallowed. This message will be displayed to the user by the WizardControl.</param>
        public override bool CanMoveOn(out string message)
        {
            message = "";
            if (this._selectedClass != null) return true;

            message = "You must select a SubClass before you can move on";
            return false;
        }

        /// <summary>
        /// Verifies whether the user can move back from this step.
        /// </summary>
        public override bool CanMoveBack()
        {
            return true;
        }

        /// <summary>
        /// Provides an interface for the developer to implement functionality to cancel any edits made as part of this
        /// wizard step. The default wizard controller functionality is to call all wizard steps cancelStep methods when
        /// its Cancel method is called.
        /// </summary>
        public override void CancelStep()
        {
            this.PropertiesSelectorControl.Model.SelectedOptions = null;
        }

        /// <summary>
        /// The text that you want displayed at the top of the wizard control when this step is active.
        /// </summary>
        public override string HeaderText
        {
            get { return "Select Properties"; }
        }



        /// <summary>
        /// Get and set the <see cref="DMSolution"/> used for this Control. Setting will set the Classes for the <see cref="ClassSelectorControl"/>
        /// </summary>
        public DMSolution Solution
        {
            get { return _solution; }
            set
            {
                _solution = value;
                ClassSelectorControl.BusinessObjectCollection = _solution == null ? null : _solution.AllClasses;
            }
        }
        /// <summary>
        /// The Selector Control that is used to select the SubClass that the properties are being selected for.
        /// </summary>
        public IBOColSelectorControl ClassSelectorControl
        {
            get { return _classSelectorControl; }
            private set { _classSelectorControl = (IBOComboBoxSelector)value; }
        }

        /// <summary>
        /// The Currently Selected SubClass for this Wizard Step
        /// </summary>
        public DMClass SelectedClass
        {
            get { return _selectedClass; }
            set
            {
                _selectedClass = value;
                this.ClassSelectorControl.SelectedBusinessObject = _selectedClass;

                if (_selectedClass == null)
                {
                    PropertiesSelectorControl.AllOptions = null;
                    return;
                }
                BusinessObjectCollection<DMProperty> dmProperties = _selectedClass.AllProperties;
                dmProperties.Sort("OrdinalPosition", true, true);
                List<string> properties = dmProperties.ConvertAll(property => property.PropertyName ?? "");
                PropertiesSelectorControl.AllOptions = properties;

                //LoadUIGrid();
                if (ReferenceEquals(this.Solution, _selectedClass.Solution)) return;

                this.ClassSelectorControl.Enabled = false;
                this.Solution = (DMSolution) _selectedClass.Solution;
            }
        }

        public ILabel Label
        {
            get { return _label; }
        }

        //This code was carried over from LGMIS, where you could edit existing ui defs.
        //There are no tests for this, so write tests if you decide to reimplement it.
        //private void LoadUIGrid()
        //{
        //    BusinessObjectCollection<UIView> uiViews = _selectedClass.UIViews;
        //    List<string> currentGridProperties = new List<string>();
        //    if (uiViews.Count > 0)
        //    {
        //        UIView uiView = uiViews[0];
        //        UIGridInfo gridInfo = uiView.UIGridInfo;
        //        if (gridInfo !=null)
        //        {
        //            BusinessObjectCollection<UIGridColumnInfo> columns = gridInfo.UIColumns;
        //            if (columns != null)
        //            {
        //                foreach (UIGridColumnInfo gridColumnInfo in columns)
        //                {
        //                    string propertyName = gridColumnInfo.PropertyName;
        //                    if (string.IsNullOrEmpty(propertyName)) continue;

        //                    currentGridProperties.Add(propertyName);
        //                }
        //            }
        //        }
        //    }
        //    this.PropertiesSelectorControl.SelectedOptions = currentGridProperties;
        //}
    }
}